package com.wss.lsl.lucene.demo.shipin.advanced.query;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.FieldCache;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.function.CustomScoreProvider;
import org.apache.lucene.search.function.CustomScoreQuery;
import org.apache.lucene.search.function.ValueSourceQuery;

/**
 * 自定义评分规则
 * 
 * @author lenovo
 * 
 */
public class MyCustomScoreQuery extends CustomScoreQuery {

	/**
	 * 
	 */
	private static final long serialVersionUID = 7591638662683789777L;

	public MyCustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery) {
		super(subQuery, valSrcQuery);
	}

	public MyCustomScoreQuery(Query subQuery) {
		super(subQuery);
	}

	@Override
	protected CustomScoreProvider getCustomScoreProvider(IndexReader reader)
			throws IOException {
		return new MyCustomScoreProvider(reader);
	}

	// 根据评分域
	private class MyCustomScoreProvider extends CustomScoreProvider {

		public MyCustomScoreProvider(IndexReader reader) {
			super(reader);
		}

		// 默认是subQueryScore*valSrcScore
		@Override
		public float customScore(int doc, float subQueryScore, float valSrcScore)
				throws IOException {
			return subQueryScore / valSrcScore;
		}
	}

}

class FilenameScoreQuery extends CustomScoreQuery {

	/**
	 * 
	 */
	private static final long serialVersionUID = 3833308275103945602L;

	public FilenameScoreQuery(Query subQuery) {
		super(subQuery);
	}

	@Override
	protected CustomScoreProvider getCustomScoreProvider(IndexReader reader)
			throws IOException {
		return new FilenameScoreProvider(reader);
	}

	// 根据filename自定义评分规则
	private class FilenameScoreProvider extends CustomScoreProvider {

		private String[] filenames = null;

		public FilenameScoreProvider(IndexReader reader) {
			super(reader);
			try {
				filenames = FieldCache.DEFAULT.getStrings(reader, "filename");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public float customScore(int doc, float subQueryScore, float valSrcScore)
				throws IOException {
			String filename = filenames[doc];
			filename = filename.toLowerCase();
			if (filename.endsWith(".css")) {
				return subQueryScore * 1.5f;
			}
			return subQueryScore / 1.5f;
		}

	}
}

class DateScoreQuery extends CustomScoreQuery {

	/**
	 * 
	 */
	private static final long serialVersionUID = -1629065305335628282L;

	public DateScoreQuery(Query subQuery) {
		super(subQuery);
	}

	@Override
	protected CustomScoreProvider getCustomScoreProvider(IndexReader reader)
			throws IOException {
		return new DateScoreProvider(reader);
	}

	// 最近一年的文档提高评分
	private class DateScoreProvider extends CustomScoreProvider {

		private long[] dates = null;

		public DateScoreProvider(IndexReader reader) {
			super(reader);
			try {
				dates = FieldCache.DEFAULT.getLongs(reader, "date");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public float customScore(int doc, float subQueryScore, float valSrcScore)
				throws IOException {
			long date = dates[doc];

			Date modifiedDate = new Date(date);
			Calendar cal = Calendar.getInstance();
			cal.set(Calendar.YEAR, -1);

			if (modifiedDate.after(cal.getTime())) {
				return subQueryScore * 1.5f;
			}
			return subQueryScore / 1.5f;
		}
	}
}
